--[[
TODO:
	people NOT on the main platform should have proximity closed
]]--

--------------------------------------------------------------------------------
-- Module Declaration
--

local mod, CL = BigWigs:NewBoss("Ji-Kun", 930, 828)
if not mod then return end
mod:RegisterEnableMob(69712) -- Ji-Kun

--------------------------------------------------------------------------------
-- Locals
--
local nestCounter = 0
local quillCounter = 0

--------------------------------------------------------------------------------
-- Localization
--

local L = mod:NewLocale("enUS", true)
if L then
	L.lower_hatch_trigger = "The eggs in one of the lower nests begin to hatch!"
	L.upper_hatch_trigger = "The eggs in one of the upper nests begin to hatch!"

	L.nest = "Nests"
	L.nest_desc = "Warnings related to the nests.\n|cFFADFF2FTIP: Untoggle this to turn off warnings if you are not assigned to handle the nests.|r"

	L.flight_over = "Flight over in %d sec!"
    L.upper = "Upper"
	L.upper_nest = "|cff008000Upper|r nest"
    L.lower = "Lower"
	L.lower_nest = "|cffff0000Lower|r nest"
	L.up = "|cff008000UP|r"
	L.down = "|cffff0000DOWN|r"
	L.add = "Add"
	L.big_add_message = "Big add at %s"
end
L = mod:GetLocale()

--------------------------------------------------------------------------------
-- Initialization
--

function mod:GetOptions()
	return {
		"nest", {-7360, "FLASH"}, 140741, 137528,
		{140092, "TANK_HEALER"}, {134366, "TANK_HEALER"}, {134380, "FLASH"}, 134370, {138923, "PROXIMITY"},
		"proximity", "berserk", "bosskill",
	}, {
		["nest"] = -7348,
		[140092] = "general",
	}
end

function mod:OnBossEnable()
	self:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT", "CheckBossStatus")

	-- eat for the hatchlings is intentionally not here, players can't do anything about it once it is casted, so we don't warn uselessly
	self:Log("SPELL_AURA_APPLIED", "PrimalNutriment", 140741)
	self:Log("SPELL_AURA_APPLIED", "Flight", 133755)
	self:Log("SPELL_CAST_START", "Caw", 138923)
	self:RegisterUnitEvent("UNIT_SPELLCAST_START", nil, "boss1")
	self:RegisterUnitEvent("UNIT_SPELLCAST_CHANNEL_START", "FeedYoung", "boss1")
	self:Log("SPELL_AURA_APPLIED", "TalonRake", 134366)
	self:Log("SPELL_AURA_APPLIED_DOSE", "TalonRake", 134366)
	self:Log("SPELL_AURA_APPLIED_DOSE", "InfectedTalons", 140092)

	self:RegisterEvent("CHAT_MSG_MONSTER_EMOTE")

	self:Death("Win", 69712)
end

function mod:OnEngage(diff)
	if not self:LFR() then
		self:OpenProximity("proximity", 8)
	end
	self:Berserk(600) -- XXX assumed
	self:Bar(134380, (diff == 4 or diff == 6) and 42 or 60) -- Quills
	self:Bar(134370, 90) -- Down Draft
	self:CDBar(134366, 24) -- Talon Rake
	nestCounter = 0
	quillCounter = 0
end

--------------------------------------------------------------------------------
-- Event Handlers
--

function mod:Caw(args)
	self:Message(args.spellId, "Attention", nil, CL["incoming"]:format(args.spellName))
	--self:CDBar(args.spellId, 18) -- 18-30s
end

do
    local prev = 0 -- GetTime()

    local white = "FFFFFFFF"
    local yellow = "FFFFFF01"
    local blue = "FF0080FF"
    local red = "FFFF0404"
    local purple = "FF9932CD"
    local green = "FF088A08"

    local nests25hc = {
        ("|c%s%s|r"):format(yellow, L["lower"]),
        ("|c%s%s|r (%s)"):format(blue, L["lower"], L["add"]),
        ("|c%s%s|r"):format(red, L["lower"]),
        ("|c%s%s|r - |c%s%s|r"):format(purple, L["lower"], yellow, L["upper"]),
        ("|c%s%s|r (%s) - |c%s%s|r"):format(green, L["lower"], L["add"], blue, L["upper"]),
        ("|c%s%s|r"):format(purple, L["upper"]),
        ("|c%s%s|r - |c%s%s|r"):format(yellow, L["lower"], red, L["upper"]),
        ("|c%s%s|r - |c%s%s|r (%s)"):format(blue, L["lower"], green, L["upper"], L["add"]),
        ("|c%s%s|r"):format(red, L["lower"]),
        ("|c%s%s|r - |c%s%s|r"):format(purple, L["lower"], yellow, L["upper"]),
        ("|c%s%s|r - |c%s%s|r (%s)"):format(green, L["lower"], blue, L["upper"], L["add"]),
        ("|c%s%s|r - |c%s%s|r"):format(yellow, L["lower"], purple, L["upper"]),
        ("|c%s%s|r - |c%s%s|r"):format(blue, L["lower"], red, L["upper"]),        
        ("|c%s%s|r (%s) - |c%s%s|r - |c%s%s|r"):format(red, L["lower"], L["add"], green, L["upper"], yellow, L["upper"]),
        ("|c%s%s|r - |c%s%s|r"):format(purple, L["lower"], blue, L["upper"]),
        ("|c%s%s|r - |c%s%s|r - |c%s%s|r"):format(green, L["lower"], yellow, L["lower"], purple, L["upper"]),
        ("|c%s%s|r - |c%s%s|r"):format(blue, L["lower"], red, L["upper"]),
        ("|c%s%s|r - |c%s%s|r - |c%s%s|r"):format(red, L["lower"], green, L["upper"], yellow, L["upper"])
    }

    local nests25n = {
        ("|c%s%s|r"):format(yellow, L["lower"]),
        ("|c%s%s|r"):format(blue, L["lower"]),
        ("|c%s%s|r"):format(red, L["lower"]),
        ("|c%s%s|r"):format(purple, L["lower"]),
        ("|c%s%s|r - |c%s%s|r"):format(green, L["lower"], yellow, L["upper"]),
        ("|c%s%s|r"):format(blue, L["upper"]),
        ("|c%s%s|r"):format(purple, L["upper"]),
        ("|c%s%s|r - |c%s%s|r"):format(yellow, L["lower"], red, L["upper"]),
        ("|c%s%s|r - |c%s%s|r"):format(blue, L["lower"], green, L["upper"]),
        ("|c%s%s|r"):format(red, L["lower"]),
        ("|c%s%s|r"):format(purple, L["lower"]),
        ("|c%s%s|r - |c%s%s|r"):format(green, L["lower"], yellow, L["upper"]),
        ("|c%s%s|r"):format(blue, L["upper"]),
        ("|c%s%s|r - |c%s%s|r"):format(yellow, L["lower"], purple, L["upper"]),
        ("|c%s%s|r - |c%s%s|r"):format(white, L["lower"], white, L["upper"]),
        ("|c%s%s|r - |c%s%s|r"):format(white, L["lower"], white, L["upper"]),
        ("|c%s%s|r"):format(white, L["lower"]),
        ("|c%s%s|r - |c%s%s|r"):format(white, L["lower"], white, L["upper"]),
        ("|c%s%s|r - |c%s%s|r"):format(white, L["lower"], white, L["upper"])
    }

    function mod:CHAT_MSG_MONSTER_EMOTE(_, msg)
        if not msg:find(L["upper_hatch_trigger"], nil, true) and not msg:find(L["lower_hatch_trigger"], nil, true) then return end

        local diff = self:Difficulty()

        if diff ~= 4 and diff ~= 6 then
            nestCounter = nestCounter + 1

            local color, text, icon
            if msg:find(L["upper_hatch_trigger"]) then
                color = "Attention"
                text = CL["count"]:format(L["upper_nest"], nestCounter)
                icon = "misc_arrowlup"
            else
                color = "Urgent"
                text = CL["count"]:format(L["lower_nest"], nestCounter)
                icon = "misc_arrowdown"
            end

            -- one message for 10h nests with a guardian
            if diff == 5 and (nestCounter == 2 or nestCounter == 4 or nestCounter == 8 or nestCounter == 12) then
                text = L["big_add_message"]:format(text)
            end
            self:Message("nest", color, "Alert", text, icon) -- XXX keep this here till all the nest rotations are 100% figured out

            local nextNest = nestCounter + 1
            if diff == 7 then -- LFR
                -- first 3 lower, second 3 upper
                if nestCounter % 6 > 2 then
                    self:Bar("nest", 40, ("(%d) %s"):format(nextNest, L["upper_nest"]), "misc_arrowlup")
                else
                    self:Bar("nest", 40, ("(%d) %s"):format(nextNest, L["lower_nest"]), "misc_arrowdown")
                end
            elseif diff == 3 then -- 10 N
                -- first 3 lower, second 3 upper with 9/10 and 15/16 happening at the same time
                if nestCounter == 8 or nestCounter == 14 then -- up and down at same time
                    self:Bar("nest", 40, ("(%d) %s + (%d) %s"):format(nextNest, L["up"], nextNest+1, L["down"]), 134347)
                elseif nestCounter == 9 or nestCounter == 15 then
                    -- no bar for second of double nests
                elseif nestCounter % 6 > 2 then
                        self:Bar("nest", 40, ("(%d) %s"):format(nextNest, L["upper_nest"]), "misc_arrowlup")
                else
                    self:Bar("nest", 40, ("(%d) %s"):format(nextNest, L["lower_nest"]), "misc_arrowdown")
                end
            elseif diff == 5 then -- 10 H
                -- first 3 lower, second 3 upper with 9/10 and 15/16 happening at the same time
                -- big adds at 2, 4, 12
                if nestCounter == 2 or nestCounter == 6 or nestCounter == 12 or nestCounter == 13 then
                    self:Bar("nest", 40, ("(%d) %s"):format(nextNest, L["lower_nest"]), "misc_arrowdown")
                elseif nestCounter == 4 or nestCounter == 5 or nestCounter == 10 or nestCounter == 16 or nestCounter == 17 then
                    self:Bar("nest", 40, ("(%d) %s"):format(nextNest, L["upper_nest"]), "misc_arrowlup")
                elseif nestCounter == 8 or nestCounter == 14 then -- up and down at same time
                    self:Bar("nest", 40, ("(%d) %s + (%d) %s"):format(nextNest, L["up"], nextNest+1, L["down"]), 134347)
                elseif nestCounter == 1 or nestCounter == 7 then
                    self:Bar("nest", 40, ("(%d) %s (%s)"):format(nextNest, L["lower_nest"], L["add"]), "misc_arrowdown")
                elseif nestCounter == 3 or nestCounter == 11 then
                    self:Bar("nest", 40, ("(%d) %s (%s)"):format(nextNest, L["upper_nest"], L["add"]), "misc_arrowlup")
                end
            end
        else
            local nests = (diff == 4 and nests25n or nests25hc)
            local t = GetTime()

            if t - prev > 5 then
                prev = t

                self:Message("nest", "Attention", "Alert", nests[nestCounter + 1], 134347)
                self:Bar("nest", 30, nests[nestCounter + 2], 134347)
                nestCounter = nestCounter + 1
            end
        end
    end
end

function mod:PrimalNutriment(args)
	if not self:Me(args.destGUID) then return end
	self:Message(args.spellId, "Positive")
	self:Bar(args.spellId, 30, CL["you"]:format(args.spellName))
end

do
	local function flightMessage(remainingTime)
		mod:Message(-7360, "Personal", remainingTime < 5 and "Info", L["flight_over"]:format(remainingTime), 133755)
	end
	function mod:Flight(args)
		if not self:Me(args.destGUID) then return end
		self:ScheduleTimer(flightMessage, 5, 5)
		self:ScheduleTimer(flightMessage, 8, 2)
		self:ScheduleTimer(flightMessage, 9, 1) -- A bit of spam, but it is necessary!
		self:ScheduleTimer("Flash", 8, -7360)
		self:Bar(-7360, 10)
	end
end

function mod:UNIT_SPELLCAST_START(_, _, _, _, spellId)
	-- UNIT event due to combat log range issues
	if spellId == 134380 then -- Quills
		self:Message(spellId, "Important", "Warning")
		self:Flash(spellId)
		local diff = self:Difficulty()
		quillCounter = quillCounter + 1
		if diff == 4 or diff == 6 then -- 25 N/H
			self:Bar(spellId, 63)
		else -- 10 N/H + LFR
			if quillCounter == 4 then
				self:Bar(spellId, 91)
			elseif quillCounter > 6 then
				self:Bar(spellId, 44) -- soft enrage it looks like
			else
				self:Bar(spellId, 81)
			end
		end
	elseif spellId == 134370 then -- Down Draft
		self:Message(spellId, "Important", "Long")
		self:Bar(spellId, 93)
	end
end

function mod:FeedYoung(_, _, _, _, spellId)
	if spellId == 137528 then -- UNIT event due to combat log range issues
		self:Message(spellId, "Positive", "Info") -- Positive because it is green!
		local diff = self:Difficulty()
		local is25 = diff == 4 or diff == 6
		self:CDBar(spellId, is25 and 30 or 41)
	end
end

function mod:TalonRake(args)
	self:StackMessage(args.spellId, args.destName, args.amount, "Urgent", "Info")
	self:CDBar(args.spellId, 22)
end

function mod:InfectedTalons(args)
	if args.amount % 2 == 0 then
		self:StackMessage(args.spellId, args.destName, args.amount, "Attention")
	end
end

